#ifdef WIN32
#define _WIN32_WINNT 0x0501
#endif

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <boost/asio.hpp>

#include "feed.h"
#include "client.h"

using boost::asio::ip::tcp;

Client::Client()
{
	proxy = false;
}

Client::Client(std::string pwd, std::string log, std::string addr, int port)
{
	password = pwd;
	login = log;
	proxyAddr = addr;
	proxyPort = port;
	proxy = true;
}

Client::~Client()
{
}

void Client::addRssFeed(std::string serv, std::string page)
{
	feedList.push_back(new feed(serv, page));
}

void Client::loadSavedFeeds()
{
	unsigned int i = 0;
	while (i < feedList.size())
	{
		std::cout << feedList[i]->getServname() << std::endl;
		++i;
	}
}

void Client::removeRssFeed()
{
}

void Client::refresh()
{
	unsigned int i = 0;
	while (i < feedList.size())
	{
		try
		{
			boost::asio::io_service io_service;
			tcp::resolver resolver(io_service);
			tcp::resolver::query query(feedList[i]->getServname(), "http");
			tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
			tcp::resolver::iterator end;
			tcp::socket socket(io_service);
			boost::system::error_code error = boost::asio::error::host_not_found;

			while (error && endpoint_iterator != end)
			{
			  socket.close();
			  socket.connect(*endpoint_iterator++, error);
			}
			if (error)
			  throw boost::system::system_error(error);

			sendRequest(socket, feedList[i]->getServname(), feedList[i]->getPagename());

			boost::asio::streambuf response;
			boost::asio::read_until(socket, response, "\r\n");
			std::istream response_stream(&response);
			std::string http_version;
			response_stream >> http_version;
			unsigned int status_code;
			response_stream >> status_code;
			std::string status_message;
			std::getline(response_stream, status_message);
			if (!response_stream || http_version.substr(0, 5) != "HTTP/")
			{
			  std::cout << "Invalid response\n";
			  return ;
			}
			if (status_code == 200)
			{
				std::string header(feedList[i]->getServname() + ".xml");
				std::ofstream file(header.c_str());
				int n;
				std::cout << "Loading " << feedList[i]->getServname() << "..." << std::endl;
				while (n = boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error))
					file << &response;
				file.close();
				if (error != boost::asio::error::eof)
				  throw boost::system::system_error(error);	
				parser(header);
			}
			socket.close();
		}
		catch (std::exception& e)
		{
			std::cout << "Exception: " << e.what() << "\n";
		}
		++i;
	}
}

void Client::sendRequest(tcp::socket &socket, std::string servname, std::string page)
{
	boost::asio::streambuf request;
	std::ostream request_stream(&request);
	request_stream << "GET " << page << " HTTP/1.0\r\n";
	request_stream << "Host: " << servname << "\r\n";
	//request_stream << "Proxy-Authorization: Basic c2F1dmFnX3I6Q2FUNztqSkI=\r\n";
	request_stream << "Accept: */*\r\n";
	request_stream << "Connection: close\r\n\r\n";
	boost::asio::write(socket, request);
}